package me.helllp.bootman.back.config.shiro;

import java.util.Set;

import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;

import com.google.common.collect.Sets;

import me.helllp.bootman.back.services.TokenService;
import me.helllp.bootman.back.utils.LocalSessionFactory;

/**
 * 基于JWT（ JSON WEB TOKEN）的认证域
 */
public class JwtRealm extends AuthorizingRealm {
	
	private TokenService tokenService;
	
	public JwtRealm(TokenService tokenService){
		this.tokenService = tokenService;
	}
	
	//	此Realm只支持JwtToken
	@Override
	public boolean supports(AuthenticationToken token) {
		return token instanceof JwtToken;
	}
	
    /**
     * 认证
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken token) {
        JwtToken jwtToken = (JwtToken) token;
        String jwt = (String) jwtToken.getPrincipal();
        
        JwtPlayload jwtPlayload = tokenService.verifyToken(jwt);

        //	进行缓存
        LocalSessionFactory.setUserId(Long.parseLong(jwtPlayload.getUserId()));
        
        return new SimpleAuthenticationInfo(jwtPlayload, Boolean.TRUE, getName());
    }

    /**
     * 授权,JWT已包含访问主张只需要解析其中的主张定义就行了
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        JwtPlayload jwtPlayload = (JwtPlayload) principals.getPrimaryPrincipal();
        SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
        
        // 解析角色并设置
        Set<String> roles = Sets.newHashSet(StringUtils.split(jwtPlayload.getRoles(), ","));
        info.setRoles(roles);
        // 解析权限并设置
        Set<String> permissions = Sets.newHashSet(StringUtils.split(jwtPlayload.getPerms(), ","));
        info.setStringPermissions(permissions);
        return info;
    }
}
